<?php
/*-------------------------------------------------------------------------------------------------
Kit Applicatif PHP
Noyau générique d'applications PHP / generic kernel for PHP applications

noyau 0.5 / PHP 4
http://code.fredbird.org/wak

controleur principal
file version 2005-11-10 10:22:06

-------------------------------------------------------------------------------------------------*/

class wakController extends wakCoreComponent {
/*-------------------------------------------------------------------------------------------------
proprietes
-------------------------------------------------------------------------------------------------*/
	// parametres par defaut
	var $default_parameters=array(
		'general'=>array(
			'showLog'=>'comment', // none|comment|xhtml
			'errorLevel'=>'warning',
			//'filter_uri_access' => true, // active ou desactive le filtrage d'accès par uri
			'alertEmail'=>'fredbird.org@gmail.com',
			//'protocol'=>'http',
			'sendPageAtZero'=>true
		),
		// composants par defaut
		'components'=>array(
			'triggermanager'=>'triggermanager-ini.wak-core.class.php',
			'eventpile'=>'eventpile.wak-core.class.php',
			//'eventmanager'=>'eventmanager-runclass.wak.class.php',
			'eventmanager'=>'eventmanager-classmethods.wak-core.class.php',
			//'config'=>'config.wak.class.php',
			'varmanager'=>'varmanager-datatree.wak-core.class.php',
			//'arraypath'=>'arraypath.wak-core.class.php',
			'libmanager'=>'libmanager.wak-core.class.php',
			'sqlmanager'=>'sqlmanager-mysql.wak-core.class.php',
			'filemanager'=>'filemanager.wak-core.class.php',
			//'navmanager'=>'navmanager-xml.wak-core.class.php',
			'pagemanager'=>'pagemanager-tfeeder-datatree.wak-core.class.php',
			'templatefeeder'=>'templatefeeder-magic.wak-core.class.php',
			//'accessmanager'=>'accessmanager.wak-core.class.php',
			//'usermanager'=>'usermanager-sql.wak-core.class.php',
			//'uripermmanager'=>'uripermissionmanager.wak-core.class.php',
			//'groupmanager'=>'groupmanager-sql.wak-core.class.php',
			//'connexionmanager'=>'connexionmanager-sql.wak-core.class.php',
			'timemanager'=>'timemanager.wak-core.class.php',
			'textxmltool'=>'textxmltool.wak-core.class.php',
			//'xmlalgorithm'=>'xmlalgorithm.wak-core.class.php',
			'sqlinterface'=>'sqlinterface-xml.wak-core.class.php'
		)
	);
	//var $parameters_file="wakcontroller.wak-config.txt";
	/*var $special_uris=array(
		'/wak-config'=>'config',
		'/wak-install'=>'install'
	);*/
	var $components; // tableau de references des composants
	var $start_time; // microtime de depart
/*-------------------------------------------------------------------------------------------------
methodes publiques / public methods
-------------------------------------------------------------------------------------------------*/

//---------------------------------------------------------------------- constructeur / constructor
	function wakController() {
		//$this->start_time=$this->getMicroTime();
		$this->start_time=WAK_START_TIME;
		// appel du constructeur parent
		$const=get_parent_class($this);
		parent::$const($controller);
		// definition des constantes d'execution
		$this->defineConstants();
		// auto-parametrage
		// $this->C=&$this;
		// $this->setOwnParameters();
		$this->log('wakcontroller (microkernel) started');
		
		$this->errorLevel($this->parameters['general']['errorLevel']);
		// durant le developpement du noyau...
		//$this->needLibrary('affvar');
		// echo '<code><pre>'; print_r($this->parameters); echo '</pre></code>';
		// creating global self-reference
		$GLOBALS['wakController']=&$this;
	}
	
	function & getSingleton() {
		$class=__CLASS__; // getting current class name
		// instanciation unique
		if (!isset($GLOBALS['singletons'][$class])) {
			// getting arguments to forward
			$args=func_get_args();
			/* building instanciation code, forwarding arguments
			creating singleton and a single global reference per class name */
			$eval='$GLOBALS[\'singletons\'][$class]=& new $class(';
			// adding arguments to constructor
			for ($f=0; $f<count($args); $f++) $eval.='$args['.$f.'],';
			// deleting last unnecessary ',' and closing call
			$eval=substr($eval,0,-1).');';
			// executing instanciation code
			eval($eval);
		}
		// throwing instance
		return $GLOBALS['singletons'][$class];
	}
	
//---------------------------------------------------------------------------- execution principale
	function run() {
		// interception des URI speciales
		/*foreach ($this->special_uris as $uri => $method) {
			if (ereg('^'.$uri,CALL_URI)) {
				$this->$method();
				$this->shutdown();
			}
		}*/
		
		// autoconfig ?
		/*if (is_readable(wakCORE_PWD_FILE) and eregi('^/wak-(install|config)',CALL_URI)) {
			$this->webConfig();
			$this->shutDown();
		}*/
		// recherche et execution des evenements de l'uri
		$this->triggerStateEvents();
		
		if ($this->parameters['general']['sendPageAtZero'])
			$this->pageThrow();
		
		// extinction propre
		$this->shutdown();
	}
	
	function shutDown($show_log=NULL) {
		$this->log("controller: shutting down");
		if ($show_log==NULL) $show_log=$this->parameters['general']['showLog'];
		// echo wakaffvar($show_log,'show_log');
		// affichage du log
		switch ($show_log) {
			case 'comment': $this->showLog(true); break;
			case 'xhtml': $this->showLog(false); break;
		}
		exit;
	}
	
	function alert($txt) {
		return mail($this->parameters['alertEmail'],"KAP alert on ".BASE_HREF,$txt);
	}
	
	function webConfig() {
		$cfg=& $this->needComponent('config');
		return $cfg->run();
	}
	
	function redirect($url,$external=false) {
		if (!$external) $url=BASE_HREF.$url;
		header('Location: '.$url);
		trigger_error("echec redirection vers $url ?");
		$this->shutDown();
	}
/*-------------------------------------------------------------------------------------------------
                                                                                                API
-------------------------------------------------------------------------------------------------*/
//-------------------------------------------------------------------------------------  evenements
	function runEvent($event,$parameters=NULL) {
		$evt=& $this->needComponent('eventmanager');
		return $evt->runEvent($event,$parameters);
	}
	
	function queueEvent($event,$priority,$parameters=NULL,$resultTo=NULL) {
		$pile=& $this->needComponent('eventpile');
		return $pile->queue($event,$priority,$parameters,$resultTo);
	}
	
	function cancelEvent($event) {
		$pile=& $this->needComponent('eventpile');
		return $pile->cancel($event);
	}
	
	function cancelAllEvents() {
		$pile=& $this->needComponent('eventpile');
		return $pile->cancelAll();
	}
//--------------------------------------------------------------------------------------- affichage
	function & pageSetTemplate($file,$path=NULL) {
		$p=& $this->needComponent('pagemanager');
		return $p->setTemplate($file,$path);
	}
	function & pageInsert($content,$path='/') {
		$p=& $this->needComponent('pagemanager');
		return $p->insert($content,$path);
	}
	function & pageThrow($page=NULL,$ignoreData=false) {
		$p=& $this->needComponent('pagemanager');
		$r=$p->throwPage($page,$ignoreData);
		return $r;
	}
	/*function & pageSetTitle($title) {
		$p=& $this->needComponent('pagemanager');
		return $p->setTitle($title);
	}*/
	function & pageSet($content,$path='/body') {
		$p=& $this->needComponent('pagemanager');
		return $p->set($content,$path);
	}
	function templateFeed($template,$data) {
		$f=& $this->needComponent('templatefeeder');
		return $f->feed($template,$data);
	}
//--------------------------------------------------------------------------------------- variables
	function & initVar($key,$value) {
		$var=& $this->needComponent('varmanager');
		return $var->init($key,$value);
	}
	
	function & setVar($key,& $value) {
		$var=& $this->needComponent('varmanager');
		$r=$var->set($key,$value);
		return $r;
	}
	function destroyVar($key) {
		$var=& $this->needComponent('varmanager');
		return $var->destroy($key);
	}
	function & getVar($key) {
		//echo affvar($this->components['varmanager']['data'],false);
		$var=& $this->needComponent('varmanager');
		$r=$var->get($key);
		return $r;
	}
	
	function & getVarIn($key,$search='tmp_post') {
		$var=& $this->needComponent('varmanager');
		$r=$var->getIn($key,$search);
		return $r;
	}
	
	function & getVars($keys) {
		$var=& $this->needComponent('varmanager');
		$r=$var->getArray($keys);
		return $r;
	}
	
	function & getVarsIn($keys,$search="tmp_post") {
		$var=& $this->needComponent('varmanager');
		$r=$var->getArrayIn($keys,$search);
		return $r;
	}
	function & storeVar($key,$value=NULL) {
		$var=& $this->needComponent('varmanager');
		$r=$var->store($key,$value);
		return $r;
	}
	
	function & urlGetVarsString($url='') {
		$var=& $this->needComponent('varmanager');
		$r=$var->urlGetVarsString($url);
		return $r;
	}
	
	function & postVarsHiddenFields() {
		$var=& $this->needComponent('varmanager');
		$r=$var->postVarsHiddenFields();
		return $r;
	}
	
	function getAllVars() {
		$var=& $this->needComponent('varmanager');
		return $var->getAll();
	}
	
	function arrayMergeRR(&$array1, &$array2) {
		$var=& $this->needComponent('varmanager');
		return $var->array_merge_recursive_replace($array1,$array2);
	}
	
	function varToXml(&$value,$key="") {
		$var=& $this->needComponent('varmanager');
		return $var->varToXml($value,$key);
	}
	function varToDeclaration($value,$key=NULL) {
		$var=& $this->needComponent('varmanager');
		return $var->varToDeclaration($value,$key);
	}
	
	function affVar($value,$key='',$cut=50) {
		$var=& $this->needComponent('varmanager');
		return $var->affVar($value,$key,$cut);
	}
//------------------------------------------------------------------------------------ abstractions
	// arrayPath
	/*function arrayPathLoad($data) {
		$a=& $this->needComponent('arraypath');
		return $a->loadData($data);
	}
	function arrayPathGetRef($path,$syntax=NULL) {
		$a=& $this->needComponent('arraypath');
		return $a->getRef($path,$syntax);
	}*/
	// xmlAlgorithm
	/*function xmlAlgorithmLoadMap($xml,$ref=NULL) {
		$x=& $this->needComponent('xmlAlgorithm');
		return $x->loadMap($xml,$ref);
	}
	function xmlAlgorithmLoad($xml,$ref=NULL,$data=array(),$maps="") {
		$x=& $this->needComponent('xmlAlgorithm');
		return $x->load($xml,$ref,$data,$maps);
	}
	function xmlAlgorithmExecute($ref,$xpath=NULL,$data=NULL) {
		$x=& $this->needComponent('xmlAlgorithm');
		return $x->execute($ref,$xpath,$data);
	}
	// sqlInterface
	function sqlInterfaceLoad($xml,$ref=NULL,$data=NULL) {
		$si=& $this->needComponent('sqlInterface');
		return $si->load($xml,$ref,$data);
	}
	function sqlInterfaceRun($action,$ref=NULL,$data=NULL) {
		$si=& $this->needComponent('sqlInterface');
		return $si->run($action,$ref,$data);
	}*/
//--------------------------------------------------------------------------------------------- SQL
	function sqlOpen($base=NULL) {
		$sql=& $this->needComponent('sqlmanager');
		return $sql->open($base);
	}
	function sqlSetDb($base) {
		$sql=& $this->needComponent('sqlmanager');
		return $sql->setDb($base);
	}
	function sqlSecureValue($value) {
		$sql=& $this->needComponent('sqlmanager');
		return $sql->secureValue($value);
	}
	function sqlExecute($query) {
		$sql=& $this->needComponent('sqlmanager');
		return $sql->execute($query);
	}
	function & sqlResult($query,$indexField=NULL) {
		$sql=& $this->needComponent('sqlmanager');
		$r=$sql->result($query,$indexField);
		return $r;
	}
	function & sqlUniqueResult($query) {
		$sql=& $this->needComponent('sqlmanager');
		$r=$sql->uniqueResult($query);
		return $r;
	}
	function & sqlTableStructure($tableName) {
		$sql=& $this->needComponent('sqlmanager');
		$r=$sql->tableStructure($tableName);
		return $r;
	}
	function sqlInsertArray($table,$data=array(),$explicitNegative=false) {
		$sql=& $this->needComponent('sqlmanager');
		return $sql->insertArray($table,$data,$explicitNegative);
	}
	function sqlLastOpSummary($mode='string') {
		$sql=& $this->needComponent('sqlmanager');
		return $sql->lastOpSummary($mode);
	}
//--------------------------------------------------------------------------- librairies et classes
	// inclusions de librairie, transmissions d'instances
	function needLibrary($name) {
		$lib=& $this->needComponent('libmanager');
		return $lib->needLibrary($name);
	}
	// retourne une instance la classe, avec passage de zéro à cinq arguments
	function & needObject($class) {
		$lib=& $this->needComponent('libmanager');
		$param=array_slice(func_get_args(),1);
		return $lib->needObject($class,$param);
	}
	// idem, pour les librairies du noyau
	function & needCoreObject($class) {
		$lib=& $this->needComponent('libmanager');
		$param=array_slice(func_get_args(),1);
		return $lib->needCoreObject($class,$param);
	}
	// renvoie la reference d'une instance unique de la classe
	// instancie la classe si nécessaire, avec passage de zéro à cinq arguments
	function & needUniqueObject($name, $class='') {
		$lib=& $this->needComponent('libmanager');
		$param=array_slice(func_get_args(),2);
		return $lib->needUniqueObject($name,$class,$param);
	}
	function needFunction($name) {
		$lib=& $this->needComponent('libmanager');
		return $lib->needFunction($name);
	}
	function needClass($name) {
		$lib=& $this->needComponent('libmanager');
		return $lib->needClass($name);
	}
	
//---------------------------------------------------------------------------- gestion des fichiers
	function fileContent($file) {
		$f=& $this->needComponent('filemanager');
		return $f->getContent($file);
	}
	function fileGetMimeType($file) {
		$f=& $this->needComponent('filemanager');
		return $f->getMimeType($file);
	}
	function fileListPath($path, $recurse=false,$ignoreDot=true) {
		$f=& $this->needComponent('filemanager');
		return $f->listPath($path, $recurse,$ignoreDot);
	}
	function fileInfo($file) {
		$f=& $this->needComponent('filemanager');
		return $f->getInfo($file);
	}
	// recherche une expression régulière dans le contenu des fichiers texte d'un chemin
	function fileRegexSearchPathContent($regex,$path="",$recurse=false,$around=false) {
		$f=& $this->needComponent('filemanager');
		return $f->regexSearchPathContent($regex,$path,$recurse,$around);
	}
	function fileRegexSearchContent($regex,$file="",$around=false) {
		$f=& $this->needComponent('filemanager');
		return $f->regexSearchContent($regex,$file,$around);
	}
	function fileregexSearchPathName($regex,$path="",$recurse=false) {
		$f=& $this->needComponent('filemanager');
		return $f->regexSearchPathName($regex,$path,$recurse);
	}
	function fileSafeUpload($postName,$path,$newName=NULL) {
		$f=& $this->needComponent('filemanager');
		return $f->safeUpload($postName,$path,$newName);
	}
	function fileVersionUpload($postName,$path) {
		$f=& $this->needComponent('filemanager');
		return $f->versionUpload($postName,$path);
	}
	/*function fileRegexSearchTextFile($regex, $file,$aroundChars=25)
	regexSearchContent($regex, $path="", $recurse=false,$around=false)*/
//--------------------------------------------------------contrôle d'accès, utilisateurs et groupes
	function accessCheckUri($uri=NULL) {
		$a=& $this->needComponent('accessmanager');
		return $a->checkUriUserPermission($uri);
	}
	// retourne l'id de l'utilisateur connecté le cas échéant
	function accessAuthenticateUser() {
		$a=& $this->needComponent('accessmanager');
		return $a->AuthenticateUser();
	}
	function accessLogOut() {
		$a=& $this->needComponent('accessmanager');
		return $a->logOut();
	}
	function accessFailPage() {
		$a=& $this->needComponent('accessmanager');
		return $a->failpage();
	}

	function userAdd($data) {
		$u=& $this->needComponent('usermanager');
		return $u->addUser($data);
	}
	function userGetById($id) {
		$u=& $this->needComponent('usermanager');
		return $u->getById($id);
	}
	function userGetIdByLoginPwd($login,$pwd) {
		$u=& $this->needComponent('usermanager');
		return $u->getIdByLoginPwd($login,$pwd);
	}
	
	function connexionCheck($key=NULL) {
		$c=& $this->needComponent('connexionmanager');
		return $c->check($key);
	}
	function connexionOpen($userId) {
		$c=& $this->needComponent('connexionmanager');
		return $c->open($userId);
	}
	function connexionClose($key) {
		$c=& $this->needComponent('connexionmanager');
		return $c->close($key);
	}
	/*function connexionGetKey() {
		$c=& $this->needComponent('connexionmanager');
		return $c->getKey();
	}
	function connexionGetTimeLeft() {
		$c=& $this->needComponent('connexionmanager');
		return $c->getTimeLeft();
	}
	function connexionGetUserId() {
		$c=& $this->needComponent('connexionmanager');
		return $c->getUserId();
	}*/
	function connexionGetInfo() {
		$c=& $this->needComponent('connexionmanager');
		return $c->getSessionInfos();
	}
	function connexionWhyUnlogged() {
		$c=& $this->needComponent('connexionmanager');
		return $c->whyUnlogged();
	}
	
	function uriPermissionIsPublic($uri=NULL) {
		$up=& $this->needComponent('uripermmanager');
		return $up->isPublicUri($uri);
	}
	function uriPermissionCheckId($id,$uri=NULL) {
		$up=& $this->needComponent('uripermmanager');
		return $up->checkIdOnUri($id,$uri);
	}
	function uriPermissionCheckIds($ids=array(),$uri=NULL) {
		$up=& $this->needComponent('uripermmanager');
		return $up->checkIdsOnUri($ids,$uri);
	}
	
	function groupGetUserGroupIds($user_id) {
		$g=& $this->needComponent('groupmanager');
		return $g->GetUserGroupIds($user_id);
	}
//-------------------------------------------------------------------------------------- navigation
	function navLoadArbo($file, $prefixUri=NULL) {
		$n=& $this->needComponent('navmanager');
		return $n->loadArbo($file, $prefixUri);
	}
	
	function navPathFromRoot($uri=NULL) {
		$n=& $this->needComponent('navmanager');
		return $n->getPathFromRoot($uri);
	}

	function navTopLevel() {
		$n=& $this->needComponent('navmanager');
		return $n->getTopLevel();
	}
	function navSameLevel($uri=NULL) {
		$n=& $this->needComponent('navmanager');
		return $n->getSameLevel($uri);
	}
	function navChildren($uri=NULL) {
		$n=& $this->needComponent('navmanager');
		return $n->getChildren($uri);
	}
	
	function navTree() {
		$n=& $this->needComponent('navmanager');
		return $n->getTree();
	}
//----------------------------------------------------------------------autour des dates etdu temps
	function dateConvert($output_format,$date=NULL,$input_format=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->convert($output_format,$date,$input_format);
	}
	function dateFr($format,$date=NULL,$input_format=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->frdate($format,$date,$input_format);
	}
	function dateWeek($date=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->getWeek($date);
	}
	function dateYear($date=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->getYear($date);
	}
	function dateSelectForm($prefix="",$date=NULL,$elements="mday_mon_year",$label=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->formSelectDate($prefix,$date,$elements="mday_mon_year",$label);
	}
	function dateCatchForm($prefix="",$output_format="php_getdate") {
		$t=& $this->needComponent('timemanager');
		return $t->catchSelectDate($prefix,$output_format);
	}
	function dateAdd($date1,$date2,$outputFormat=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->add($date1,$date2,$outputFormat);
	}
	function dateSoustract($date1,$date2,$outputFormat=NULL) {
		$t=& $this->needComponent('timemanager');
		return $t->soustract($date1,$date2,$outputFormat);
	}
	function timeTaken() {
		return $this->getMicroTime()-$this->start_time;
	}
//----------------------------------------------------------------------- autour du texte et du xml
	function xmlEntities(& $str) {
		$t=& $this->needComponent('textxmltool');
		return $t->xmlEntities($str);
	}
	function xmlEntitiesDecode(& $str) {
		$t=& $this->needComponent('textxmltool');
		return $t->xmlEntitiesDecode($str);
	}
//----------------------------------------------------------------------------- gestion des erreurs
	/*function notice($txt) {
		trigger_error($txt,E_USER_NOTICE);
	}
	function warning($txt) {
		trigger_error($txt,E_USER_WARNING);
	}
	function error($txt) {
		trigger_error($txt,E_USER_ERROR);
	}*/
	
	function log($msg) {
		$this->log[]=sprintf('%.3f',$this->getMicroTime()-WAK_START_TIME)
		.': '.$msg;
	}
	
	function errorLevel($level) {
		ini_set('display_errors',true);
		switch ($level) {
			case 'all':
				error_reporting(E_ALL);
				break;
			case 'error':
				error_reporting(E_ERROR | E_PARSE | E_USER_ERROR);
				break;
			case 'warning':
				error_reporting(E_ERROR | E_PARSE | E_USER_ERROR | E_WARNING | E_USER_WARNING);
				break;
			case 'notice':
				error_reporting(E_ERROR | E_PARSE | E_USER_ERROR | E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE);
				break;
			case 'none':
				error_reporting(0);
				break;
			case 'system':
			default:
				error_reporting();
		}
	}
//------------------------------------------------------------------------------------------ divers
	function checkPhpVersion($minimum="4.3.0") {
		if (PHP_VERSION<$minimum) return false;
		else return true;
	}
	
	function checkExtension($extension) {
		return extension_loaded($extension);
	}

/*-------------------------------------------------------------------------------------------------
methodes propres
-------------------------------------------------------------------------------------------------*/

	// instancie au besoin le composant requis
	function & needComponent($name) {
		$name=strtolower($name);
		//echo '<pre>'; print_r($this->components); echo '</pre><br>';
		if (isset($this->components[$name])) return $this->components[$name];
		if (!isset($this->parameters['components'][$name])) {
			trigger_error("wakcontroller: unknown component : $name",E_USER_ERROR);
		}
		$file=WAK_CORE_PATH.'classes/'.$this->parameters['components'][$name];
		include_once($file);
		$class='wak'.$name;
		$this->components[$name]=&new $class($this);
		//$this->log("+$name:".count($this->components));
		return $this->components[$name];
	}
	// definit les constantes utiles
	function defineConstants() {
		// methode d'appel
		define('REQUEST_METHOD',strtolower($_SERVER['REQUEST_METHOD']));
		define('BASE_PATH',dirname($_SERVER['PHP_SELF']));
		if ($_SERVER['SERVER_PORT']=='443' 
		or (isset($this->parameters['protocol']) and $this->parameters['protocol']=='https'))
			define('PROTOCOL','https');
			else define('PROTOCOL','http');
		$baseUrl=PROTOCOL."://".$_SERVER['HTTP_HOST'].BASE_PATH;
		// wiping finale slash
		if (substr($baseUrl,-1,1)=='/') $baseUrl=substr($baseUrl,0,-1);
		define('BASE_URL',$baseUrl);
		if (BASE_PATH!="/")
			// on supprime du debut de l'uri l'emplacement du site
			$callUri=substr($_SERVER['REQUEST_URI'],strlen(BASE_PATH));
			//$callUri=str_replace(dirname($_SERVER['PHP_SELF']),'',$_SERVER['REQUEST_URI']);
		else $callUri=$_SERVER['REQUEST_URI'];
		// suppression variables GET
		if ($pos=strpos($callUri,'?')) $callUri=substr($callUri,0,$pos);
		
		//if (substr($callUri,0,1)=='/') $callUri=substr($callUri,1);
		define('CALL_URI',$callUri);
		// on retire les slashs initiaux et finaux
		$baseUri=substr($callUri,1);
		if (substr($baseUri,-1)=='/') $baseUri=substr($baseUri,0,-1);
		define('BASE_URI',$baseUri);
		// base href
		/*if (substr(BASE_URL,-1)=='/') define('BASE_HREF',BASE_URL);
		else */
		define('BASE_HREF', BASE_URL.'/');
		//define('URL',BASE_URL.CALL_URI);
		// define('URL',BASE_URL.$_SERVER['REQUEST_URI']);
		// chaine de variables get
		define('QUERY_STRING','?'.$_SERVER['QUERY_STRING']);
		
		if ($_SERVER['QUERY_STRING']) define('URL',BASE_URL.CALL_URI.'?'.$_SERVER['QUERY_STRING']);
		else define('URL',BASE_URL.CALL_URI);
		// ip
		define('IP',$_SERVER['REMOTE_ADDR']);
		// referer
		define('REFERER',isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:NULL);
		//$this->log('requests constants defined');
		//define('CORE_PATH',$this->core_path);
		//define('LIBRARY_PATH',$this->parameters['library_path']);
	}
	
	function triggerStateEvents() {
		$this->log("controller: start triggering events");
		$trig=& $this->needComponent('triggermanager');
		$triggers=$trig->getStateEvents();
		// echo '<p>Triggers: '.wakAffVar($triggers).'</p>';
		$pile=& $this->needComponent('eventpile');
		$pile->loadPile($triggers);
		/*$log="pile construite :";
		foreach ($pile->getFuturePile() as $evt => $info)
			$log.=' '.$evt;*/
		$this->log('controller: pile built : '.join(' ',array_keys($pile->getFuturePile())));
		// ajout d'un evenement par defaut si nécessaire et défini
		if ($pile->isEmpty()
		and isset($this->parameters['defaultEvent'])
		and $default=$this->parameters['defaultEvent']) {
			$pile->queueEvent($default['event'],$default['priority'],$default['params']);
		}
		$evt=& $this->needComponent('eventmanager');
		$var=& $this->needComponent('varmanager');
		//echo affvar($this->eventPile->future);
		while ($event=$pile->getNextEvent()) {
			// echo '<p>triggering '.wakAffVar($event).'<p>';
			$params=$var->retrieveParams($event['params']);
			//$this->log("execution ".$event['event'].' ('.$event['priority'].') '.trim($event['params']));
			$result=$evt->runEvent($event['event'],$params);
			// importing result
			if ($event['result_to'] and is_string($event['result_to']))
				$this->sendResultTo($result,$event['result_to']);
			wakLog("controller: ran event ".$event['event']);
		}
	}

	function showLog($htmlComment=true) {
		$log="";
		if ($htmlComment) $log.="<!-- webAppKit log :\n"; else $log.='<div id="waklog">webAppKit log :<br />';
		if ($htmlComment) $nl="\r\n"; else $nl="<br />\r\n";
		$var=$this->needComponent('varmanager');
		if (function_exists('memory_get_usage')) $memory=memory_get_usage();
		else $memory="unknown";
		$log.="base path : ".BASE_PATH
		." | base URL : ".BASE_URL
		." | base URI : ".BASE_URI
		." | call URI : ".CALL_URI
		." | method : ".REQUEST_METHOD
		." | port : ".$_SERVER['SERVER_PORT'];
		if (REQUEST_METHOD=="get") $log.=$nl.$this->affvar($_GET,'_GET');
		if (REQUEST_METHOD=="post") $log.=$nl.$this->affvar($_POST,'_POST');
		if ($_COOKIE) $log.=$nl.$this->affvar($_COOKIE,'_COOKIE');
		$log.=$nl.join($nl,$this->log)
		//.$nl."time spent generating page : ".sprintf('%.3f',$this->getMicroTime()-$this->start_time)." seconds"
		.$nl."memory use : ".$memory
		//.$nl.$this->affvar($var->allvars(),'all vars')
		;
		if ($htmlComment) $log.="\n -->"; else $log.='</div>';
		echo $log;
		//$this->pageManager->setblock('log',$log);
	}
	// filtre l'accès selon l'uri d'appel
	/*function filterUriAccess($failPage=NULL) {
		if ($this->accessCheckUri()) return true;
		// acces interdit
		$this->accessfailpage();
		$this->shutDown();
	}*/

	function getMicroTime() {
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}
	
	// traitement des URI speciales
	/*function config() {
		$conf=$this->needComponent('config');
		$conf->run();
	}*/
	/*function install() {
	
	}*/
	
	/* sends a (event) result to its destination : page, var
	*/
	function sendResultTo($result,$to) {
		if (!eregi('^((pageinsert:)|(pageset:)|(pagethrow:)|(data:))(.+)$',$to,$found))
			return $this->setVar($to,$result);
		// echo wakAffvar($found,$to);
		$domain=$found[1];
		$more=$found[6];
		switch ($found[1]) {
			case 'pageinsert:':
				return $this->pageInsert($result,$more);
			case 'pageset:':
				return $this->pageSet($result,$more);
			case 'pagethrow:':
				return $this->pageThrow($result,$more=='ignoredata');
			case 'data:':
				return $this->setVar($more,$result);
				break;
			default:
				return false;
		}
	}
}
?>
